package com.framework.core.mybatis.ddl;

import com.framework.core.mybatis.context.TableContext;
import com.framework.core.mybatis.context.TableInfo;
import com.framework.core.mybatis.mapper.DdlMapper;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 *  主要执行类
 *  created by zzg
 *  2024-12-06
 */
public abstract class AbstractMybatisDdlFactory implements IMybatisDdlFactory {
    protected SqlSessionFactory sqlSessionFactory;

    @Override
    public void generalStatements(TableContext context) {
        this.sqlSessionFactory = context.getSqlSessionFactory();
        List<TableInfo> tableInfoList = context.getTableInfoList();
        List<TableInfo> existsList = new ArrayList<>();
        List<TableInfo> notExistsList = new ArrayList<>();
        // 区分create和update
        doQueryTable(tableInfoList, existsList, notExistsList);
        // 执行create
        List<String> sqlList = createTableStatements(notExistsList);
        executeBatch(sqlList);
        // 执行update
        List<String> updateSqlList = updateTableStatements(existsList);
        executeBatch(updateSqlList);
    }

    protected void doQueryTable(List<TableInfo> allList, List<TableInfo> existsList, List<TableInfo> notExistsList) {
        allList.forEach(it -> {
            if (select(it.getTableName())) {
                existsList.add(it);
            } else {
                notExistsList.add(it);
            }
        });
    }

    public void executeBatch(List<String> sqlList) {
        try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
            DdlMapper ddlMapper = sqlSession.getMapper(DdlMapper.class);
            sqlList.forEach(it -> {
                ddlMapper.execute(it);
            });
            sqlSession.commit();
        }
    }

    public boolean select(String tableName) {
        try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
            DdlMapper ddlMapper = sqlSession.getMapper(DdlMapper.class);
            return ddlMapper.select(tableName);
        }
    }

    public List<String> selectColumns(String tableName) {
        try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
            DdlMapper ddlMapper = sqlSession.getMapper(DdlMapper.class);
            return ddlMapper.selectColumns(tableName);
        }
    }

    @Override
    public abstract void execute(TableContext context);

    protected abstract List<String> createTableStatements(List<TableInfo> tableInfoList);

    protected abstract List<String> updateTableStatements(List<TableInfo> existsList);
}
